﻿using IQReportes.ViewModels;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Data.Entity;
using IQReportes.Utils;

namespace IQReportes.Models.Logica
{
    public class LogicaUsuario
    {
        public static int numFilas = 10;
        public static int cantUsuarios;
        LogicaPerfil logicaPerfil = new LogicaPerfil();
        GlobalDbContext db = new GlobalDbContext();

        public UsuarioBasicoViewModel getUsuarioBasicoById(string id)
        {
            int idUsuario = Int32.Parse(id);
            var usuario = db.usuarios.Include(x=>x.perfil).Where(x => x.idUsuario == idUsuario).First();
            return new UsuarioBasicoViewModel(usuario);
        }
        public bool actualizarUsuarioCambioClave(CambiarClaveViewModel usuario)
        {
            Usuario u = db.usuarios.Where(x => x.idUsuario == usuario.id).First();
            u.vcNombre = usuario.nombre;
            if (usuario.claveNueva != null)
            {
                u.vcClave = Crypto.Hash(usuario.claveNueva);
            }
            u.vcEmail = usuario.email;
            db.Entry(u).State = EntityState.Modified;
            db.SaveChanges();
            return true;
        }
        public CambiarClaveViewModel getUsuarioCambioClave(){
            string _usuario = System.Web.HttpContext.Current.Session["Usuario"] as string;
            var usuario = db.usuarios.Include(x => x.perfil).Where(x => x.vcUsuario.CompareTo(_usuario) == 0).First();
            return new CambiarClaveViewModel(usuario);
        }
        public UsuarioViewModel getUsuarioActualConf()
        {
            string _usuario = System.Web.HttpContext.Current.Session["Usuario"] as string;
            var usuario = db.usuarios.Include(x=>x.perfil).Where(x => x.vcUsuario.CompareTo(_usuario) == 0).First();
            return new UsuarioViewModel(usuario);
        }
        public string getNombreUsuario(string usuario)
        {
            return db.usuarios.Where(x=>x.vcUsuario.CompareTo(usuario)==0).First().vcNombre;
        }
        public List<UsuarioBasicoViewModel> getListUsuariosPagina(int pagina)
        {
            int skip = numFilas * (pagina - 1);
            List<UsuarioBasicoViewModel> ListUsuarios = getListUsuarios();
            cantUsuarios = (int)Math.Ceiling(ListUsuarios.Count / (LogicaUsuario.numFilas * 1.0));
            var usuarios = ListUsuarios.Skip(skip).Take(numFilas);
            return usuarios.ToList();
        }
        public bool esAdministrador()
        {
            //string usuario = System.Web.HttpContext.Current.User.Identity.Name;
            
            //string perfil = (new LogicaPerfil()).getPerfilByUsuario(usuario);
            string usuario = System.Web.HttpContext.Current.Session["Usuario"] as string;
            if (usuario == null) return false;
            var gg  = db.usuarios.Include(x=>x.perfil)
                .Where(x=>x.vcUsuario.CompareTo(usuario)==0).First();
            bool admin = gg.perfil.bAdmin;
            string perfil = admin == true ? "1" : "0";
            System.Web.HttpContext.Current.Session["Nombre"] = getNombreUsuario(usuario);
            System.Web.HttpContext.Current.Session["Admin"] = perfil;
            return admin;
        }

        public List<UsuarioBasicoViewModel> getListUsuarios()
        {
            var usuarios = db.usuarios.ToList();
            return usuarios.Select(x => new UsuarioBasicoViewModel(x)).ToList();
        }
        public List<UsuarioViewModel> getListUsuariosByPerfil(string perfil)
        {
            List<UsuarioViewModel> usuarios = new List<UsuarioViewModel>();
            return usuarios;
        }

        public bool crearUsuario(UsuarioBasicoViewModel usuario)
        {
            
            string encriptado = Crypto.Hash(usuario.clave);
            usuario.clave = encriptado;
            //TODO limpiar estos 3 valores harcode
            usuario.txBotonDateSeleccion = 0;
            usuario.txInstitucion = 0;
            usuario.pcInstitucion = 0;

            Usuario nuevo = usuario.extract();
            db.usuarios.Add(nuevo);
            db.SaveChanges();
            (new LogicaModulo()).crearModulosXUsuario(nuevo.idUsuario);
            logicaPerfil.aumentarCantidadPerfil(usuario.idPerfil);
            return true;
        }
        public string getClaveAntigua(string id)
        {
            int idUsuario = Int32.Parse(id);
            return db.usuarios.Where(x=>x.idUsuario==idUsuario).Select(x=>x.vcClave).ToList()[0];
        }
        public string getClaveUsuario(string claveNueva, string id)
        {
            string claveAntigua = getClaveAntigua(id) ;
            if (claveNueva == null)
            {
                return claveAntigua;
            }
            else
            {
                return Crypto.Hash(claveNueva);
            }

        }
        public bool actualizarUsuario(UsuarioBasicoViewModel usuario)
        {
            usuario.clave =getClaveUsuario(usuario.claveEdit, usuario.id);
            logicaPerfil.actualizarCantidadPerfil(usuario);
            db.Entry(usuario.extract()).State = EntityState.Modified;
            db.SaveChanges();
            return true;
        }
        public bool eliminarUsuario(string id)
        {
            //TODO eliminar relaciones
            Usuario usuario = db.usuarios.Find(Int32.Parse(id));
            (new LogicaModulo()).eliminarModulosXUsuario(usuario.idUsuario);
            logicaPerfil.disminuirCantidadPerfil(usuario.idPerfil);
            db.usuarios.Remove(usuario);
            db.SaveChanges();
            return true;
        }

        public void actualizarUsuarioConf(UsuarioViewModel usuario)
        {
            usuario.clave = getClaveUsuario(usuario.clave, usuario.id);
            (new LogicaModulo()).actualizarModulosXUsuarioConf(usuario);
            db.Entry(usuario.extract()).State = EntityState.Modified;
            db.SaveChanges();
        }
        public bool usuarioRepetido(int? idUsuario,string _usuario)
        {
            var usuarios = db.usuarios.Where(x=>x.vcUsuario.ToUpper().CompareTo(_usuario.ToUpper())==0);
            if (idUsuario != null)
            {
                usuarios = usuarios.Where(x => x.idUsuario != idUsuario);
            }
            var listaUsuarios = usuarios.ToList();
            return listaUsuarios.Count > 0 ? true: false ;
        }

        public string[] validarClaveNueva(string claveAntigua, string claveNueva, string claveNuevaRepetida, int idUsuario)
        {
            List<string> errores = new List<string>();
            if (claveAntigua == null && claveNueva == null && claveNuevaRepetida == null)
            {
                return errores.ToArray();
            }
            
            string bdClaveAntigua = db.usuarios.Where(x => x.idUsuario == idUsuario).First().vcClave;
            if ( claveAntigua == null  || claveNueva == null || claveNuevaRepetida == null){
                if ( claveAntigua == null ){
                    errores.Add("claveAntigua");
                    errores.Add("El campo clave antigua es requerido");
                }
                if ( claveNueva == null ){
                    errores.Add("claveNueva");
                    errores.Add("El campo clave nueva es requerido");
                }
                if ( claveNuevaRepetida == null ){
                    errores.Add("claveNuevaRepetida");
                    errores.Add("El campo repetir nueva clave es requerido");
                }
                return errores.ToArray();
            }
            if (Crypto.Hash(claveAntigua).CompareTo(bdClaveAntigua)!=0)
            {
                errores.Add("claveAntigua");
                errores.Add("Clave ingresada incorrecta");
            }
            if ( claveNueva.CompareTo(claveNuevaRepetida)!=0 ){
                errores.Add("claveNuevaRepetida");
                errores.Add("Clave nueva no coincide con la clave ingresada");
            }
            //"claveNueva" "claveNuevaRepetida"
            return errores.ToArray();
        }
    }
}